{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 分类训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2051, 60000, 28, 28)\n",
      "47040000\n"
     ]
    }
   ],
   "source": [
    "import struct\n",
    "with open('./train-images.idx3-ubyte','rb') as f:\n",
    "    buffer = f.read(4*4) \n",
    "    head = struct.unpack('>iiii',buffer)\n",
    "    print(head)\n",
    "    length = head[1] * head[2] * head[3]\n",
    "    print(length)\n",
    "    buffer = f.read(length)\n",
    "    data = struct.unpack('>{}B'.format(length),buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data)\n",
    "type(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000, 28, 28)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "imgs = np.reshape(data,(head[1],head[2],head[3]))\n",
    "imgs.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "for i in range(5,10):\n",
    "    plt.imshow(imgs[i],cmap = 'gray')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\think\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\utils\\deprecation.py:85: DeprecationWarning: Function fetch_mldata is deprecated; fetch_mldata was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n",
      "c:\\users\\think\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\utils\\deprecation.py:85: DeprecationWarning: Function mldata_filename is deprecated; mldata_filename was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_mldata\n",
    "mnist = fetch_mldata('MNIST original',data_home = './')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DESCR': 'mldata.org dataset: mnist-original',\n",
       " 'COL_NAMES': ['label', 'data'],\n",
       " 'target': array([0., 0., 0., ..., 9., 9., 9.]),\n",
       " 'data': array([[0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        ...,\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mnist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * DESCR数据集描述\n",
    "   * data包含一个数组，每个实例为一行，每个特征为一列\n",
    "   * target包含一个带标签的数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "X,y = mnist['data'],mnist['target']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000, 784)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000,)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "some_digit = X[36000]\n",
    "some_digit_image = some_digit.reshape(28,28)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(some_digit_image,cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[36000]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 建立测试集和训练集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train,X_test,y_train,y_test = X[:60000],X[60000:],y[:60000],y[60000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([48036, 23548,  7709, ..., 56230, 49944, 47528])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将数据集合交叉洗牌，交叉验证时，每个子集合数据分布均匀，有些机器学习算法对训练实例的顺序敏感\n",
    "import numpy as np\n",
    "shuffle_index = np.random.permutation(60000)\n",
    "shuffle_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train,y_train = X_train[shuffle_index],y_train[shuffle_index]\n",
    "X_train"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练一个二元分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, ..., False, False, False])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 识别数字5，二元分类5或者非5\n",
    "# 创建目标向量\n",
    "y_train_5 = (y_train == 5)\n",
    "y_train_5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False, False, False, ...,  True, False, False],\n",
       "       [False, False, False, ...,  True,  True, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       ...,\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_5.reshape(20,-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_5 = (y_test == 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# SGD 梯度下降分类器，适合非常大的数据集，独立处理训练集数据，一次一个，适合在线学习\n",
    "from sklearn.linear_model import SGDClassifier\n",
    "\n",
    "sgd_clf = SGDClassifier(random_state = 42)\n",
    "sgd_clf.fit(X_train,y_train_5)\n",
    "\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 性能考核"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用交叉验证验证精度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.9455, 0.9635, 0.9697])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 评估分类器比评估回归器要困难很多\n",
    "\n",
    "# cv=3，3个折叠 正确率达到95%以上\n",
    "from sklearn.model_selection import cross_val_score\n",
    "cross_val_score(sgd_clf,X_train,y_train_5,cv=3,scoring = \"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 把所有的图片都分类为非5\n",
    "from sklearn.base import BaseEstimator\n",
    "class no5Classifier(BaseEstimator):\n",
    "    def fit(self,X,y=None):\n",
    "        pass\n",
    "    def predict(self,X):\n",
    "        return np.zeros((len(X),1),dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False],\n",
       "       [False],\n",
       "       [False],\n",
       "       ...,\n",
       "       [False],\n",
       "       [False],\n",
       "       [False]])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.zeros((len(X),1),dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.9082 , 0.9109 , 0.90985])"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "no_5_clf = no5Classifier()\n",
    "cross_val_score(no_5_clf,X_train,y_train_5,cv=3,scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * 准确率超过90%，因为5的图像只有10%，预测一张图不是5,90%的几率是正确的\n",
    "   * 说明准确率无法成为分类器的首要性能指标，特别是当处理偏科数据集时，某些类比其他类更为频繁"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 混淆矩阵\n",
    "   * 评估分类器性能的更好方法\n",
    "   * A类别实例被分为B类别次数\n",
    "   * 通过混淆矩阵的5行3列知道分类器将数字3和5混淆多少次"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, ..., False,  True, False])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_predict\n",
    "y_train_pred = cross_val_predict(sgd_clf,X_train,y_train_5,cv=3)\n",
    "y_train_pred"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 与cross_val_score相比\n",
    "   * 同样执行交叉验证\n",
    "   * 返回的不是评估分数，是每个折叠的预测\n",
    "   * 每一个实例在模型预测时使用的数据，在训练期间从未见过"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[53837,   742],\n",
       "       [ 1684,  3737]], dtype=int64)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "confusion_matrix(y_train_5,y_train_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * 行表示实际类别，列表示预测类别\n",
    "   * 1.1 53837 被正确的分类为 非5 真负类\n",
    "   * 1.2  742  被错误的分类为  5  假正类\n",
    "   * 2.1 1684  被错误的分类为 非5 假负类\n",
    "   * 2.2 3737  被正确的分类为  5  真正类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正类预测的准确率 被称为分类器的精度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 精度和召回率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8343380218798839"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import precision_score,recall_score\n",
    "\n",
    "precision_score(y_train_5,y_train_pred) # 精度 = 3737/(3737+742)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6893562073418189"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5,y_train_pred)  #召回率 = 3737/(1684+3737)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * 说明预测一张值为5的图是5，有83.4%的概率是正确的，有68.9%的概率被检测出来\n",
    "   * 精度和召回率合成单一指标，称为F1分数，谐波平均值\n",
    "   * 平均值平等对待所有的值，谐波平均值会给予较低值更高的权重，只有召回率和进度都很高值，才会获得较高的F1分数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 谐波平均值\n",
    "   * F1分数对那些具有相近精度和召回率的分类器更有利，但是这不一定符合实际应用的期望\n",
    "   * 有时候精度更重要，有时候召回率更重要\n",
    "   * 训练一个分类器检测内容是否健康的视频，可能拦截了很多健康的视频（低召回率），但是保留下来的都是健康的视频（高精度）\n",
    "   * 不能增加精度的同时降低召回率，反之亦然"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.754949494949495"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import f1_score\n",
    "f1_score(y_train_5,y_train_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 精度/召回率权衡"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * SGDClassifier对每个实例基于决策函数计算一个阀值，大于阀值为正类，否则为负类\n",
    "   * 阀值降低，召回率提高，精度降低，反之亦然\n",
    "   * sklearn不可以直接设置阀值，可以访问决策函数\n",
    "   * SGDClassifier默认阀值为0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3744.73624467])"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回决策值decision_function\n",
    "y_scores = sgd_clf.decision_function([some_digit])\n",
    "y_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "threshold = 0 #阀值为0\n",
    "y_some_digit_pred = (y_score > threshold)\n",
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#提高阀值，召回率就会降低\n",
    "threshold = 20000    #将阀值提高到20000\n",
    "y_some_digit_pred = (y_score > threshold)  #将这张图预测为非5\n",
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * 应该根据实际业务需求确定阀值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 通过设置参数method = \"decision_function\"来返回决策值，而不是预测结果\n",
    "y_scores = cross_val_predict(sgd_clf,X_train,y_train_5,cv=5,method=\"decision_function\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000,)"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_scores.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import precision_recall_curve\n",
    "precisions,recalls,thresholds = precision_recall_curve(y_train_5,y_scores) # 得到精度，召回率，阀值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用matplotlib绘制精度和召回率相对于阀值的函数图\n",
    "def plot_precision_recall_vs_threshold(precisions,recalls,thresholds):\n",
    "    plt.plot(thresholds,precisions[:-1],\"b--\",label=\"Precision\",linewidth=2)\n",
    "    plt.plot(thresholds,recalls[:-1],\"g--\",label=\"Recall\",linewidth=2)\n",
    "    plt.xlabel(\"Threshold\",fontsize=16)\n",
    "    plt.legend(loc=\"upper left\",fontsize=16)\n",
    "    plt.ylim([0,1])\n",
    "\n",
    "plt.figure(figsize=(8,4))\n",
    "plot_precision_recall_vs_threshold(precisions,recalls,thresholds)\n",
    "plt.xlim([-25000,25000])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过选择阀值来实现最佳的精度-召回率权衡"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将精度设置为90%，阀值大概在2500左右\n",
    "y_train_pred_90 = (y_scores > 2500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8964613368283093"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "precision_score(y_train_5,y_train_pred_90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.630879911455451"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5,y_train_pred_90)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "   * 获得了一个90%精度的分类器，但是如果召回率太低，没有什么意义\n",
    "   * 如果工作中实际要求99%的精度，应该关注召回率是多少"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 阀值与精度的关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "def plot_precision_vs_recall(precisions,recalls):\n",
    "    plt.plot(recalls,precisions,'b-',linewidth=2)\n",
    "    plt.xlabel(\"召回\",fontsize=16)\n",
    "    plt.ylabel(\"精度\",fontsize=16)\n",
    "    plt.axis([0,1,0,1])\n",
    "\n",
    "plt.figure(figsize=(8,6))\n",
    "plot_precision_vs_recall(precisions,recalls)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ROC曲线\n",
    "   * 本质是 真正类率tpr和假正类率fpr 的关系（被错误地分为正类的负类实例比例）\n",
    "   * 与召回-精度曲线类似"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import roc_curve\n",
    "fpr,tpr,thresholds = roc_curve(y_train_5,y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAf0AAAF6CAYAAAATeYHoAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOzdd3hUZf7+8fczk14gAUIVFRSlCKFEiiAiSLPs6qoUKYKiqKuuul87IIvo6uqia18UFHQFdX+r7loQEcUOBDQooqICIr2m15nn98dMADGQBJI5mTP367q8OJk5OfPJCLnnqcdYaxERERH38zhdgIiIiISGQl9ERCRCKPRFREQihEJfREQkQij0RUREIoRCX0REJEIo9EVERCJEyEPfGNPEGPPRYZ6PNsb8zxjziTHmslDWJiIi4mYhDX1jTCowB0g8zGnXASustb2Bi4wxySEpTkRExOVC3dL3AcOBnMOc0w94OXj8IZBRyzWJiIhEhKhQvpi1NgfAGHO40xKBTcHj3UCTg08wxlwJXAmQmJjYrW3btjVbqIiI1BhrwWL3HfutxW+Dj1tLmb98O3iLz2/x+eHAmLAHHFgsxWV+vB5DYYkPa8FnLV4DBSU+vB7zm4w5eLv5/a9XN0V5DGV+S0KMN/Dz+S0xxk/Ojk2UFRcSl5xCUe7endbatGpfuzYKPkp5QDyQDSQFv/4Va+1MYCZARkaGzczMDGmBIiJHq7jMR2GJLxBy1uL3Q15xKUWlfnIKS8kuLMUYg89vySkqZXd+CYkxXiwEA3N/iFoOCFEs1sKS73ZQPyGaGK8Hv7X7wtYS+N7ya/gsLFu3i5Ob1oPg8/vP3/86fmvJLSpjS3YRjZJigYOvGTj3wOMyfyCgj8ThYjk2+OfBY7/1juiV9vOYQKPUY8BgwAQeKyoNfMiI9ho6tqiPwWAMeMyv/8wpLKXMb+nZuiHJcVEUl/mJj/bSKCkWjwGPx+AxBq8HSsr8HNcwkcbJsUR7PTRIjCEu2ovX89tGcX5+Pq1btyYhNpqZc55l+PDhGGM2HMnPWBdDfwXQB/g3kA587mw5IhJurA20GHOLyijx+fe1LP1++6uQzC4sxee3+0LQby1+f+B4a04RsVGBwAy0PgPfu3Z7LikJMfy0I58t2YWs3Z5HfLSX+Ghv8HV+HYZlPsumvYUkxUbtu06J78iCsDZlbdxb5XN35hVX+/px0R68xuDxBD7IFJT4aNM4Ca/HsDu/hJSEaFqkxOP1eNiRW0TT+nGkJsRg9gVrIFw9wVb8jtxiOh1Tn6JSP8ekxtOsfhxxMV6iPIaU+BiM4bfBzP5Qj/J6SIqNCj5WaQ+0I0pLS4mOjiYxMZFHH32UU089lVatWh3VNR0NfWNMf6C9tfaxAx6eA7xljDkdaA8sdaQ4Eak2v98GgvSg8PNbKCguI7/Ex5a9hfy0M5/YKM++rtny4F29OYcm9eJYum43KfHRgWtW0Dr1W9i0t5D84jIaJsXg9we6QLfmFDn7BhxGXnFZhY+nJkTjDbYAjYFtOcV0bpnC5r2FnNg4ifrxgef3FJSQEh9DWnKgnWuCrdHyQDTBUOOAx3fkFtOjVQMSYqKC55SHXuBcjyfYoiXQCq0XF/WrkCx/nfLHDAaLDYbxr4P0wPAMnLs/YBNi6mL7sm776quvGDFiBFOnTuXiiy9m2LBhNXJdR/5PWGv7Bf9cDCw+6LkNxpiBBFr7U6y1vtBXKBJerLXkFZexM6+E7TlFGGN+E5LlrduiUh+78kqIj/Hg9/ObcM5cvxuftcRHeynzW37akYcxga7Nz3/azQlpicEu5zJ255cQF+3B5w905Tpxp+6C3YUVPu4xge5pgKb14vYH474WY+ADx8bdhXQ7LvVXXbvlLcp1O/Ppelwq3gO6Zj3BMO14TAp5RWW0bBDPMakJHJMaHwzv/SFYfh1joF5cNNFR5d27Zl+rV+RA1lqeeuopbrrpJlJSUmjQoEGNXr9Ofvyy1m5m/wx+EdfyB8c8S/1+Ckt8bM8p5qtN2Vgs63fmE+X1YAi0Yr/ZkkP9+Gg27CrAHwzlghIf32w53GKYmvfjjvxffV1U+tuu6npxUcREeQ8I0EAQbtobCNhf9hTQtmk92jRO+tU4p8cEWrRtm9ajzOfnpCbJwXFVc0ALdH+o+i00SorZF6RRHkNMlId6cdEKVAk7u3fv5oorruA///kPQ4YMYc6cOTRu3LhGX6NOhr5IOLI2MFabX+xjZ14x/8vajCc4EWvVpmya1oulzG8pKfOzPaeYZet310odCTFeGifH0jg5rsLJRuXBmhDjpXn9+F+3bj2BQN2aXUTG8ak0SoolymMoKvXTIjWe2KjAOGhibBRRnkBLNTUhmiiP51etXBGpvkWLFvHf//6XBx98kBtvvBGPp+ZX1Sv0RSrg81t25RVTXOanuMxH1sZsftlTSH5JGV9u3MumPYU0rhfLFz/vpXFyLNtzqz+x6UBJsVFEeQ17C0pJS44lxuthQLvGbM8ppl2zesRGe4jyBJ4/uWkyPr+laf04YqM8RHk8NEuJC86oFpFw4vP5yMrKomvXrgwbNoyMjAxat25da6+n0BfXKinzB8ea/RQEu853F5Tg91s27ikg2uvh603ZJMdF8+XGPcRHe/luay6bs6s2GWzT3sBY8sGBnxjjJb/Ex7ENEij1+bmk+7F4vYbsglLaNEkmymOIi/bQPCWetORYmtaLU+tYJAJt2rSJ0aNH8/nnn/Pdd99x7LHH1mrgg0JfwkhhSaDb/Lutufy0M48oj4cP1+7AE5xktmLDXprWj+XrTTU3xl3eVZ5X7MPrgc4tU+hybCoArRsl0jwlnoQYL/Xjo4mL9pIYq39SIlK5N954g3HjxlFYWMiTTz5Jy5YtQ/K6+g0ldUZ+cRmf/7SLNVtyyCkq4/ttuRQU+1i2fjcJMYFJa5U5eP1wjNdDbJQHj8eQXVhKXLSH9GNSSI6L4pc9hXRv1YC9BaW0a1YPY+C4Bgl0aplCs3pxmggmIjXOWstNN93Eww8/TOfOnZk/fz4nn3xyyF5foS+1rqjUx9bsIrZkF7H4222s3Z5Hg8QY9haUsuqXvezMK6n0GuWBHxftoajUT6tGiaQmRHPq8Q3YnV9C91YNSE2IAaB5Sjz14qNoVj++wt2tREScYozB6/Vy/fXXc//99xMXFxfS11foy1Hbml3ED9vz2JxdiMcYFq7eypLvdxAb5SGnqOINSQ4nLtrD0FOa0ax+HGnBWejHpMZzQuMkktR9LiJhxlrL3LlzadOmDaeddhoPPPCAY/N49BtUDunbrTls2lPIt1tzef/b7azflU9achw+f2CC3MHrtQ928J7bLRvEk1tURqtGiZx5cmOObZCAx2NokRLPCWmJJMREERMV6hs/iojUntzcXK6++mr+9a9/MWbMGE477TRHJ+4q9AVrLZkb9vDS8o18+P0O9haWUnKIm2Qcqiu+fnw0RaU+Mo5PpWVqAo2SYjmrfROObZBAclwU0V6FuYhElszMTEaMGMG6deu4++67uf32250uSaEfaUrK/Hy9OZuvN2Uz5fXVVfqes9o1ITUhmqS4KPqc2IgWqfFEeQxej4fkuCgaJMRo0puIyAGWLVtGnz59aNq0KUuWLKFPnz5OlwQo9F2tpMzP99ty+dfSDaz6JZvVmytfyvb7zs0Z0qEpbZvV45jUeLXQRUSqwe/34/F46NatG5MmTeLaa6+t8f3zj4ZC32WKSn1Mef1r3lm9jezC0kOe16F5Pboem0rDpBjG9DyOhtrNTUTkqCxatIibbrqJBQsW0Lx5c6ZMmeJ0Sb+h0A9zK3/ew7X/WklibBRrt+dVeE7vExtiMJzdsRmnHp/KCWlJ6o4XEakhpaWlTJkyhfvvv5+2bduSk5ND8+bNnS6rQgr9MGKt5efdBTz7yXo+/H4H63blH/JWpr1aN2TKee1p2zRZW7yKiNSSdevWMXLkSJYuXcoVV1zBww8/TEJCgtNlHZJCvw7bnlvEO6u38d6abXzw3Y7Dntv3pDSu6XcCxzdMpGn90G72ICISqaZNm8a3337LSy+9xLBhw5wup1LGHqqpGCYyMjJsZmam02UctZIyP5/8sJPH3/+BojLfYfePb9esHokxXsaedjxDOjTV2nYRkRAqKChg9+7dHHPMMezdu5c9e/bQqlWrkNZgjFlhrc2o7veppe8gay3zlm3kzte+OmQ3PQRu7DKm13H0bN1Q3fUiIg766quvGD58OImJiSxdupSUlBRSUlKcLqvKFPoOWL8zn5te/pKVP++t8Pm+J6Vx5emtadcsWbPqRUTqAGstTz31FDfeeCOpqak88sgjeDzh18uq0A+RbTlFPPTu98xfvvE3z7VsEM/fL+5M91Z1Zy2niIgEZGdnM378eF599VWGDBnCnDlzaNy4sdNlHRGFfi3y+S33vb2Gpz9aV+Hzl/dpxR1nt9Od4ERE6rCYmBg2bNjAgw8+yI033hiWLfxyCv1asC2niDtf/ZpFa7b95rlB7ZtwWZ9W9Gzd0IHKRESkKnw+H4899hiXXXYZycnJLF26lKio8I/M8P8J6pCdecVcOTfzN2P1PVs34ObBbel2XKpDlYmISFX98ssvjB49miVLlhAXF8fEiRNdEfig0K8x323NZfDDH/7qsct6t2LKee0dqkhERKrrf//7H+PHj6eoqIjnnnuOsWPHOl1SjVLoH6XswlLOeeQjftlTuO+xqee1Z1zv0K7ZFBGRo/P4449z7bXX0qVLF+bNm8fJJ5/sdEk1TqF/hHx+y4VPfsqXG3/dlf/SlT3pofF6EZGwc+655/Lzzz8zbdo0YmPduVxaO/JVk7WWh979nkcW//Crx28d0par+50QsjpEROToWGuZM2cOb7/9NvPmzQurWfnakS9E2k1ZQFGpf9/X4047nrvOa69d8kREwkhOTg5XX301L774Iv369SMvL4969eo5XVatU+hXQ8ep7+wL/MbJsXx4y5nERXsdrkpERKpj+fLljBw5kvXr13P33Xdz++234/VGxu9yhX4VWGvpc//75BaVAZAcG8WyO89yuCoREamu0tJShg0bht/vZ8mSJfTu3dvpkkJKoV8FQ//xEZv2Bmbnn9+5OQ+P6OJwRSIiUh07duwgNTWV6OhoXn31VY477jhSUyNv75TwmbXgkPnLfubbrbkAnHlymgJfRCTMvPvuu3Ts2JFp06YB0Llz54gMfFDoH9aH3+/gtv98BcBJTZKYPe5UhysSEZGqKi0t5bbbbmPw4ME0aNCAiy++2OmSHKfu/UPYmVfM2NnLgMCkvXdu6KsZ+iIiYWLdunWMHDmSpUuXcsUVV/Dwww+TkJDgdFmOU+gfwlXPr9h3/PafTlfgi4iEkT179rBu3TpefvlltfAPoO79Ctz671VkbtgDwCMju9AwyZ07M4mIuEl+fj7/+te/AOjatSvr1q1T4B9EoX+QsbOX8VLmRgCu7ncCv0tv7nBFIiJSmVWrVpGRkcGYMWNYvXo1gLrzK6DQP8Dqzdl8+P0OAPqc2Ihbh7R1uCIRETkcay1PPPEE3bt3Z+/evbz77rt06NDB6bLqLI3pB1lrOeeRj/d9/cKEHg5WIyIiVTFu3Djmzp3L0KFDee6552jcuLHTJdVpCv2gW/69at/xq9ec5mAlIiJSVYMGDSI9PZ0bbrghrG6Y4xSFPrBmSw6vrPgFgEnntKPLsZG5aYOISF3n8/m45557aNasGVdccQWjRo1yuqSwEvEfi/KLyxj6j4+AwDj+hNNbO1yRiIhU5JdffmHAgAHcddddLF++3OlywlLEt/Qvfuqzfcd/u6iTg5WIiMih/Pe//2X8+PEUFxczZ84cxo4d63RJYSmiQz+vuIxvtuQAgX31m6fEO1yRiIgcbM2aNZx//vl07tyZ+fPnc9JJJzldUtiK6NAfO2vpvuMnRnVzsBIRETlYdnY29evXp127drz66qsMGTKE2FhtlnY0InZMf3tOESt/3gvA3b/vQHyM1+GKREQEAkuon3vuOY477jg+/fRTAH7/+98r8GtAxIb+I4vX7jse3fM4BysREZFyOTk5jBo1ivHjx9OlSxeOO06/n2tSRIa+z2954fOfAbh+QBvdTEdEpA5Yvnw5Xbp04eWXX2b69OksWrSIFi1aOF2Wq0TkmH6XaQv3HV/T7wQHKxERkXLvvvsuZWVlLFmyhN69eztdjitFXEvf77fkFJUBMOLUlsRFayxfRMQp27Zt47PPAkunb731VrKyshT4tSjiWvqf/bRr3/F9F2pdvoiIUxYuXMjYsWOJiYnhhx9+ICYmhpSUFKfLcrWIa+l//MNOAC7oonEiEREnlJaWcttttzF48GAaNmzIm2++SUxMjNNlRYSIa+k/teRHAAa1b+JwJSIikScnJ4dBgwaxdOlSrrzySh566CHd9z6EIqqln19chrWB41NbNXC2GBGRCJScnMwpp5zCyy+/zD//+U8FfohFVOgvWrNt33GjJG3yICISCvn5+fzxj39k7dq1GGN45plnuPjii50uKyJFVPf+3xd+D8Afumo8X0QkFFatWsXw4cP57rvv6NSpE23atHG6pIgWMS39jbsL+Hl3AQCX92nlcDUiIu5mreXxxx+ne/fuZGdns2jRIiZOnOh0WREv5KFvjJlljPnMGDPpEM+nGmPeMsZkGmP+WVOv+9LyjQBEew0dmtevqcuKiEgF/vnPf3LttdcyYMAAsrKy6N+/v9MlCSEOfWPMHwCvtbYX0NoYU1E/zxjgX9baDCDZGJNRE6/9xAc/APDw8C41cTkREalAcXExAJdeeimzZs3ijTfeIC0tzeGqpFyoW/r9gJeDxwuBPhWcsws4xRiTArQENh7ti+7ILcYfnLV/2gkNj/ZyIiJyEJ/Px1/+8hc6d+5Mbm4u8fHxXHbZZbq3SR0T6tBPBDYFj3cDFS2W/xg4DrgeWBM871eMMVcGu/8zd+zYUemLrtmSs+84NVEbQIiI1KRffvmF/v37M3XqVDIyaqRzVmpJqEM/D4gPHicd4vXvAq6y1k4DvgXGH3yCtXamtTbDWptRlW6jrzdnA9D3JHUxiYjUpNdff5309HRWrFjBnDlzeP7550lOTna6LDmEUIf+CvZ36acD6ys4JxXoaIzxAj0Ae7Qv+sA73wEw9JSmR3spEREJ8vv9PPDAAxx33HGsXLmSsWPHOl2SVCLU6/RfAz4yxjQHhgIjjDHTrbUHzuT/K/AsgS7+z4B5R/OCuUWl+3bh69+28dFcSkREgG+//ZaGDRuSlpbGf/7zH+rXr09srDY8Cwchbelba3MITOb7HDjTWpt1UOBjrV1mre1grU2y1g601uYdzWsuW7d/SkCTenFHcykRkYhmrWX27Nl069aNm266CYDGjRsr8MNIyNfpW2v3WGtfttZuDcXrZW7YA8DonseG4uVERFwpOzubSy65hMsvv5wePXpw//33O12SHAHX78j3bXDm/qnH6wY7IiJHYvXq1XTt2pVXXnmF6dOn8+6779K8eXOny5Ij4Pq999//LrCkr12zeg5XIiISnho3bkyTJk14/vnnOe2005wuR46Cq1v6ecVl+45bNUp0sBIRkfCybds2brnlFsrKykhLS+OTTz5R4LuAq0P/zVWbAUhLjiXa6+ofVUSkxixcuJBOnTrx6KOPsnLlSgDtrOcSrk7Ct74KzBVU176ISOVKSkq45ZZbGDx4MGlpaSxfvpzu3bs7XZbUIFeP6S/5PjCeP+LUlg5XIiJS940fP54XX3yRiRMnMmPGDBISEpwuSWqYa0Pf59+/kZ+23xUROTSfz4fX6+XPf/4zf/jDH7jwwgudLklqiWtDf1de8b7jpFjX/pgiIkcsPz+f66+/npiYGJ588km6du1K165dnS5LapFrx/R/2BHYyE9zT0REfisrK4uMjAyeffZZGjRogLVHfZsTCQOuDf2sjYE7653VrqK794qIRCZrLY899hg9evQgOzubRYsWcc8992h2foRwbeiv35kPQP34aIcrERGpOzZt2sTtt9/OgAEDyMrKon///k6XJCHk2sHulzI3AjCovVr6IiJff/01HTp04JhjjmHZsmW0bdtWrfsI5NqWfrlTWtR3ugQREceUlZUxdepU0tPTeeGFFwBo166dAj9CubKlX1Cyf/vdZvV1O10RiUwbN25k1KhRfPTRR4wZM4bzzz/f6ZLEYa4M/fU7C/Yd69OsiESiN998k7Fjx1JcXMzcuXMZM2aM0yVJHeDK0C/fiU+b8ohIJGvVqhXz5s2jTZs2TpcidYQrx/Qz1+8G4IQ03VlPRCLHmjVrePbZZwE455xzWLp0qQJffsWVof/NlhwATmqS7HAlIiK1z1rLrFmzyMjI4M477yQvL7A5mdfrdbgyqWtcGfpbsosAOLmpQl9E3C07O5uRI0cyYcIEevbsSWZmJklJSU6XJXWUK8f0k2KjyCsu45jUeKdLERGpNcXFxXTv3p0ff/yRe++9l1tuuUWtezks14V+cZmPvOLAkr0GCTEOVyMiUvOstRhjiI2N5cYbb6RTp06cdtppTpclYcB13fsbdweW6x3bIIEor+t+PBGJcFu3bmXo0KG8/fbbAFx11VUKfKky16Xihl2B0E9NVCtfRNxl4cKFpKens2TJEnbu3Ol0ORKGXBf6323LBaC41OdwJSIiNaOkpIRbbrmFwYMHk5aWRmZmpjbbkSPiutAv11Tb74qIS7z++us88MADXHXVVSxfvpwOHTo4XZKEKddN5NuTXwJAj1YNHa5EROTo/Pzzzxx77LFcdNFFfPLJJxq7l6Pmupb+xt2FALTQcj0RCVP5+flcdtlldOjQgXXr1mGMUeBLjXBdS3/jnsBEvhYpCn0RCT9ffvklI0aM4Pvvv+eOO+6gZcuWTpckLuK6lv7qzYEteBsnxzpciYhI9Tz22GP06NGDnJwcFi1axPTp04mKcl3bTBzkqtD3++2+44ZJWrInIuHlq6++YuDAgWRlZdG/f3+nyxEXctVHyG25RfuOE2Jc9aOJiEstWbKEevXq0aVLFx599FGio6MxxjhdlriUq1r663bkA6B/LyJS15WVlXHXXXfRv39/Jk2aBEBMTIwCX2qVq5rD2YWlADStpzX6IlJ3bdy4kVGjRvHRRx8xduxYHnvsMadLkgjhqtBftyvQ0u/eqoHDlYiIVOzrr7+mb9++lJaW8vzzzzN69GinS5II4qrufU+wW6ykzO9wJSIiFWvbti3Dhw9n5cqVCnwJOVeF/t6CQPf+KS3qO1yJiMh+a9asYejQoezcuZOoqCiefPJJ2rRp43RZEoFcFfrFZYGb7MRGuerHEpEwZa1l1qxZZGRksGLFCn788UenS5II56p0zA629GOjvQ5XIiKRLjs7m5EjRzJhwgR69epFVlYWPXr0cLosiXCuCv2fdwe24PVoxYuIOOzmm2/m3//+N/feey8LFy6kWbNmTpck4q7Z+ykJgV34Yryu+iwjImHC7/eTnZ1Namoq99xzD+PHj6dXr15OlyWyj6tCf0dwRz7dYU9EQm3r1q2MHTuWgoICPvjgA9LS0khLS3O6LJFfcVWTeGtOIPSPSUlwuBIRiSTvvPMO6enp+zbb8Xo1r0jqJteEvs9v2ZZTDECzFO3IJyK1r6SkhJtvvpkhQ4bQuHFjMjMzufLKK7WVrtRZrgn9vQUl+46jNaYvIiFQXFzMa6+9xlVXXcWyZcvo0KGD0yWJHJZrxvR35wdC/xiN54tILXv99dcZNGgQycnJrFixgnr16jldkkiVuKZJnF8S2Jjnlz2FDlciIm6Vl5fH+PHjOf/883n88ccBFPgSVlzT0t+ZGxjP79laN9sRkZr35ZdfMnz4cNauXcvkyZO54YYbnC5JpNpcE/oFpYGWfnk3v4hITXnppZcYO3YsjRo14r333uPMM890uiSRI+Ka7v0ft+cBcFKTZIcrERG36dq1KxdccAFZWVkKfAlrrgn9vOIyAEp9uq2uiBy9JUuWcP3112OtpU2bNsyfP59GjRo5XZbIUXFN6BcFu/ePa5jocCUiEs7Kysq466676N+/PwsWLGDXrl1OlyRSY1wT+uV7YaQG998XEamujRs3cuaZZzJt2jTGjBnDypUr1boXV3HNRL41W3IBaJio0BeR6vP5fJx11lls3ryZF154gVGjRjldkkiNc03op8RHA1Dq15i+iFRdUVER0dHReL1eZs6cSYsWLTjxxBOdLkukVrime798It/xGtMXkSpas2YN3bt354EHHgDgjDPOUOCLq7km9LMLSwGoH2zxi4gcirWWZ555hm7durF161bS09OdLkkkJEIe+saYWcaYz4wxkyo57wljzHlVvW5+SaClnxTrmhELEakF2dnZjBw5kiuuuILTTjuNrKwshg4d6nRZIiER0tA3xvwB8FprewGtjTFtDnHe6UBTa+3/qnrtjbsDe+6nJKilLyKH9s033/Daa69x7733snDhQpo1a+Z0SSIhE+qWfj/g5eDxQqDPwScYY6KBp4H1xpjfV+WiB27IUy9OoS8iv+b3+1m8eDEAvXr1Yv369dx+++14PK4Z4RSpklD/jU8ENgWPdwNNKjhnLPAN8DeguzHmuoNPMMZcaYzJNMZk7tixg4Ji377nPB5T81WLSNjasmULgwYNYsCAAaxYsQKApk2bOlyViDNCHfp5QPkN75MO8fpdgJnW2q3AC8BvNrq21s601mZYazPS0tLIKQpM4mucHFs7VYtIWFqwYAHp6el8+umnPP3003Tt2tXpkkQcFerQX8H+Lv10YH0F5/wAtA4eZwAbKrtoQUmgpb89eHtdEZFJkyYxdOhQmjZtSmZmJhMmTMAY9QRKZDvq0DfGeIIT76riNWCMMWYGMAxYbYyZftA5s4AzjTEfAtcAD1Z20YLgzP1Ox9Svct0i4m4tW7bkmmuuYenSpbRv397pckTqhErXtxljYoA/A/cBcdbawuDjccBwAhPz3gESKruWtTbHGNMPGAj8LdiFn3XQObnAxdX5IXYEW/g+v63Ot4mIy7z44ot4vV6GDx/OxIkTnS5HpM6pSkvfA9wMXAdMOeDxF4A7AAOUVvUFrbV7rLUvBwO/RuQWBdV5UEIAACAASURBVFr6ynyRyJSXl8e4ceMYNWoUc+bMwVr9MhCpSFV2sikB8oG3gExjzGdAGwLL77pZawuMMb7DfH+tK9+Yp0GiluuJRJovvviCESNGsHbtWiZPnsyUKVM0di9yCJWGvrXWb4wptdb+YIy5EfgZ+AJYBvzeGPPy4a9Q+8o/1Kclafa+SCT56aef6NmzJ2lpaSxevJh+/fo5XZJInVbdPWu3Wmu/NMZ0AR4B2gOf1XxZ1bN2e+C2uo3rxTlciYiEQllZGVFRUbRu3Zp//OMfXHTRRbrvvUgVVHn2vjGmO/D/jDFDCCyl+wnYZq1dTmBc3zENEmIA2KkleyKu98EHH3DSSSfxxRdfAHDVVVcp8EWq6LChb4zpaYx5PfjlF8ADBJbd7SYwwz41uPwu3hgzI/jfw8aYp2q16oPkBXfkO7lpcihfVkRCqKysjClTptC/f3+io6O1ha7IEaise781ga1zo4FXganAnwispbdADnACgQ8PrYLf4wVC2s9e3r0f5dUvARE3+vnnnxk1ahQff/wx48aN49FHHyUpKcnpskTCzmFD31r7IvCiMeYXAgF/P4GwHwC8TmBt/uXAWmvtBbVc6yE1DY7lF5U6uohARGrJs88+S1ZWFi+88AKjRo1yuhyRsFXVpnGJtfYSYA9QHygCLgLqAccR+CDgmPK77DWrr4l8Im5RWFjIN998A8Add9zBqlWrFPgiR6m6/eFPAe2AXQS6/jOstStqvKpqKg3uyqPufRF3+Oabb+jRoweDBg2isLCQ6Ohojj/+eKfLEgl7laakCexyEWuMaQDMJzC+n0hgyV7j2i2vanbkBGbtx3i1IYdIOLPWMnPmTDIyMti2bRvPPPMM8fHxlX+jiFRJVdbpxxIYux8CzLPWfg1gjBkLzDXGnAbE1F6JlSu/tW6wl19EwlBhYSGXXnopr7zyCmeddRbPP/+87nsvUsOq0h9eBlxLoJV/W/mD1tq3gYcBP4EPBo6pHx/Yfjcprrp7DYlIXREbG0txcTH33Xcf77zzjgJfpBZUZRveMuBfwS/zD3rur8Hu/261UFuVrfolG4B6Cn2RsOL3+5kxYwbDhg3j2GOP5bXXXtO++SK16KhnvtmAVTVRzJFqmBQYXYjWRD6RsLFlyxYGDRrEzTffzJw5cwAU+CK1rEopaYyJNcb8xxgTG/y6kTGmsTEm0RjjM8YkHnDuXGNM79oquCK+4Oz9lATdZU8kHLz99tukp6fz6aef8vTTTzNp0iSnSxKJCJVtw1v+sdsP/D74J8Bs4B2glMC++8XB8+sBI4DmtVHsoWzJLgIgLtobypcVkSMwf/58zj77bJo2bUpmZiYTJkxQC18kRCpr6b9ujPmdtbYUwFpbaoy5gsBM/j9ba0sCD9uy4PljCWzg81qtVVyB2KjAj5EQo9AXqats8B7Y55xzDlOmTGHp0qW0b9/e4apEIsshQ98Y4yFwk515weV5GGNaAn8HbrHWLj7o/DjgBuCu8g8JoVISXKsXG6XQF6mLXnjhBfr06UNhYSHJycn85S9/0fp7EQccMvSttX5r7V0E7qY3JvjwI8BSa+3DFXzLX4EtwMwar/IwLGAteAx4PeoiFKlL8vLyGDduHGPGjMHj8ZCbm+t0SSIRrSpL9t4C3jLG+IFbgTwIjPfbQH+dMcb8HTgf6GmtDekWOeVdhtqCV6Ru+eKLLxgxYgQ//PADU6ZMYfLkyURFaVmtiJMO+y/QGLMAKAh+aYH7AE9wFv9eY0z34HPnAb2stdtqrdJDCGY+JWXajk+krrDWcs0115Cfn8/ixYs544wznC5JRKi8pb+S4Mx8Ai35dsBLBLbd3Qx8CvwDOAaYYoz5U6jH88tDPy3Z0U0BRQTYuXMnUVFRpKSk8OKLL5KcnEyjRo2cLktEgg7bJ26tvcNa+xcCk/cgcCvdpODjj1lrHyXQA9AZOBV4ularrYA/eFffGHXvizjq/fffp1OnTlx77bUAtGrVSoEvUsdU5S57fwUWEQj304FRxphrDzzHWvs9gXX8Q40xv6uNQg+lfAZBTJRCX8QJZWVlTJ48mQEDBlCvXj3+7//+z+mSROQQKtuc5yZgAvAnAGvtT8Ao4K/GmNblpwWf20xgzP+uWqu2AjbY0l+3M7+SM0Wkpm3cuJEzzjiD6dOnM27cOFasWEHnzp2dLktEDqGy5vHXwLnAMgis3Q+uz38DeLCC8+cApxhjTqnRKg+jfEy/Q/N6oXpJEQnyeDxs3bqVF198kdmzZ5OYmFj5N4mIYyob019orV1KYOKeITCmD4EW/e+MMSdDYG/+4Pm7CWzoc0GtVXxwjcGWvrbgFQmNwsJCHnnkEfx+Py1atODbb79l5MiRTpclIlVQ1YFwS2CWvh/AWpsF9AQ2AEsIdvEHzQPeq8EaDyt4rx2ivdqYR6S2rV69mu7du/OnP/2JDz74AIDoaN3oSiRcVCn0rbUl1tobrbU5BzyWaa0tstaeaa0tOuDxf1hrP62NYitSfoe9olKt0xepLdZaZs6cyamnnsr27dtZsGAB/fv3d7osEammsJ/yXn5zroKSssOfKCJH7MYbb2TixIn07t2brKwsBg8e7HRJInIEKt0T0xgTBTSz1m6swrknAPdZay+uieKqJNi9f3xDTSASqS0XX3wxzZo14+abb8bjCfu2gkjEqspG2J2Aj4GE8geMMU2Bt4DTDuzaB5II3HY3ZIKZT5TG9EVqjM/n4/777ycnJ4f77ruP3r1707t3b6fLEpGjVJWP7EXAwVvrlgLpQMlBj5dUcG6tKl+y51XrQ6RGbN68mUGDBnHnnXeyYcMG/H7NlxFxi6okpS/434HKIHD73YMed+C3Q/Aue7qtrshRe+utt0hPT+ezzz7jmWee4cUXX1R3voiLhP19LsuCs/e9Cn2Ro7J9+3Yuuugi2rRpw/z582nXrp3TJYlIDQv70PfbQHfFnvyDRxpEpCq2bdtGkyZNaNy4MQsWLKB79+7ExcU5XZaI1IKq9tvVN8b8VP4fkAWYAx8LPr6o9kqtWPmSPd1aV6T6XnjhBU488UTmzZsHQN++fRX4Ii5W1ZZ+EfCXKpzXHLj5yMupPmsD2wE2TIoJ5cuKhLXc3FyuvfZa5s6dy+mnn06fPn2cLklEQqCqoV9srZ1T2UnBvfhDGvolZX7igGivJhuJVMXKlSsZMWIEP/74I1OnTuXOO+8kKirsR/pEpArC/l96+QS+7bnFDlciEh5+/PFHCgsLef/99+nbt6/T5YhICFU79I0xE4DT+e0yPoD6R13REWqlHflEDmnHjh18/vnnnHfeeVx88cWcffbZug2uSASqSugbfj3hLwFoQHCt/kGSaqKo6rDB3Xm0I59Ixd5//31GjRpFfn4+GzZsICUlRYEvEqGqEvpxwf8AsNY+AjxS0YnGmHZAyO6wBwduw6sxfZEDlZWVMXXqVO69915OOukk3nrrLVJSUpwuS0QcVGnoW2u/5IDQr0QMEH9UFVVT+Ta82pFPZL/S0lL69+/Pxx9/zGWXXcYjjzyi1r2I1MytdY0xnYwxXuAroElNXLOqissCUwu0I5/IftHR0QwZMoQXX3yRWbNmKfBFBKhC6BtjehhjDnleMOy/ANIAL9Cs5sqrXFRwX/CcwpDe50ekziksLOSaa67hgw8+AODOO+9k5MiRzhYlInVKVVr68zhM97611kdgsl8xMBpYFPwgEBLlO/I1qaddxCRyrV69mu7du/Pkk0+ydOlSp8sRkTqqKhP5SoBiY8zU4NcV3UnPEljCdwPw7+AHgZDQmL5EMmstTz/9NDfccAPJycksWLCAwYMHO12WiNRRVQn98pD/E7AK6AN8DvQE1rJ/vX5H4ASgfw3XWCUehb5EoP/+979MnDiRgQMHMnfuXJo2bep0SSJSh1VnIp8FBhHoyv9D8M8ZwLTg8fnAS9baXTVd5OGLCjT1PUahL5EjNzcXgPPOO4/58+ezYMECBb6IVOpIZu9b9i+PP/Cxp4C/H3VFR1INoGX6Egl8Ph/33HMPJ5xwAj///DMej4fhw4fj8egfgIhU7pDd+8EZ+08T2H2vL4GZ+fueruBbdlhrc2q2vMqVf/pQS1/cbvPmzYwePZr333+fkSNHUr++Y7tei0iYOtyYfjSBW+UmAW8R2HinzlLoi5u9+eabjBs3joKCAmbPns24ceMw+jsvItV0yD5Ba22xtXYo8DOB4M+u5FptjTEX12RxVVHqC8wz1OY84mbz58+nefPmrFixgvHjxyvwReSIVPUue/YQfx5oIDAOeOUoa6qW8iV75eEv4hZr167F7/dz8skn8+STTxIVFUVcnPajEJEjV9XZPyb439Lgn4uCj98J3Bc8fhqIMcYMrdEKK1Hewk+KrfZdgkXqrOeff56uXbty1VVXAZCUlKTAF5GjVp2W/vTg8XMHPWcIzNovAh4CrgDePtSFjDGzgPbAm9ba6Yc5rwmwwFrbpSoFxkaFbBNAkVqTm5vLH//4R55//nn69u3L3LlznS5JRFykKqEfA8RZaytcjmcCg4t/JzC7fy5wlzEm2lr7m83wjTF/ALzW2l7GmNnGmDbW2rWHeN0HqcId+/btyOfVGKeEt3Xr1jFo0CB++uknpk6dyqRJk/B69WFWRGpOVUL/cfbvuleROAKt/Vhr7VZjTP+KAj+oH/By8Hghgd39fhP6xpj+QD6wtbLiSv2BsfxoLdSXMNe8eXPatWvHrFmz6Nu3r9PliIgLVZqU1tqHrLXFh3m+EGgFbAt+/cVhLpcIbAoe76aC2/AaY2KAycBth7qIMeZKY0ymMSbT5y/fka+SH0SkDtqxYwcTJ04kOzub2NhY/vvf/yrwRaTW1Ejz2Fq7wVpb0Yz+g+Wxv8s+6RCvfxvwhLV272Feb6a1NsNam1Hewo+NVjeohJfFixeTnp7Oc889x+eff+50OSISAULdJ76CQJc+QDqwvoJzzgL+aIz5AOhsjHnmcBcs/6zh1bplCRNlZWXceeednHXWWdSrV49ly5bpzngiEhKhXuf2GvCRMaY5MBQYYYyZbq2dVH6CtXZf36Yx5gNr7YSqXFjd+xIubrnlFh566CEuu+wyHnnkERITE50uSUQiREhD31qbY4zpR2Ajn79Za7cCWYc5v1+l1wz+qVvrSl1XUlJCTEwMf/7zn+nRowfDhw93uiQRiTAhn/Jurd1jrX05GPg1RnvvS11VUFDAxIkTOffcc/H7/bRo0UKBLyKOCPt1buXTBzWmL3XR119/Tffu3Zk5cyZdu3bF79d20SLiHNfsXavbiUtdYq3ln//8JzfeeCP169dn4cKFDBw40OmyRCTCuSYq1b0vdUleXh733nsvZ5xxBllZWQp8EakTwr6lv2/JnibySR2wYsUKOnbsSHJyMp988gktWrTAo24oEakjwv63UfnsfTX0xUk+n4977rmHHj168MADDwDQsmVLBb6I1Clh39Ivp4l84pTNmzczevRo3n//fUaOHMl1113ndEkiIhVyT+ire18csHjxYoYPH05BQQGzZ89m3LhxGH0AFZE6yhWhbwz6RSuOSEtL48QTT+TZZ5+lbdu2TpcjInJYrhhwVNe+hNL333/PX//6VwA6duzIp59+qsAXkbDgitDXcj0Jlblz59K1a1cefPBBNm/eDKiXSUTChztC3xU/hdRlubm5jBkzhksvvZRu3bqRlZVF8+bNnS5LRKRaXDGmr5a+1CZrLf3792flypVMnTqVSZMm4fV6nS5LRKTaFPoih+D3+zHGYIxh8uTJpKSk0Ldv38q/UUSkjnJFx7hW60lN2759O+eeey6PPfYYAL/73e8U+CIS9twR+kp9qUHvvfce6enpLF68mJiYGKfLERGpMe4IfXXvSw0oLS3ljjvuYODAgaSmprJs2TImTpzodFkiIjXGFaHv89vKTxKpRGZmJvfddx+XX345y5cvp1OnTk6XJCJSo1wxkS+7sNTpEiSMrVmzhnbt2tGrVy+ysrLo2LGj0yWJiNQKV7T0W6TEO12ChKGCggImTpzIKaecwtKlSwEU+CLiaq5o6WtzHqmur7/+mhEjRrB69WpuvfVWunbt6nRJIiK1zh2hr4l8Ug3PPPMM1113HfXr12fhwoUMHDjQ6ZJERELCFW1khb5UR3Z2NmeccQZZWVkKfBGJKC4JfacrkLruk08+YcGCBQDceOONvPXWWzRp0sThqkREQssloa/Ul4r5fD6mT5/OGWecweTJk7HW4vF48GgiiIhEIFf85lPoS0U2bdrEWWedxeTJkxk2bBjvvfeeboMrIhHNFRP59HtcDrZp0ybS09MpLCzk2Wef5dJLL1Xgi0jEc0Xoq6Uv5ay1GGNo3rw51157LSNGjKBt27ZOlyUiUie4o3vfFT+FHK3vv/+evn37smbNGowxTJ06VYEvInIAV8SlWvqRzVrLnDlz6Nq1K9988w2bN292uiQRkTrJFaGvsdrIlZuby5gxYxg3bhwZGRmsWrWKAQMGOF2WiEid5IrQX7Mlx+kSxCEPPfQQ8+bNY9q0abz33nu0aNHC6ZJEROosV0zkSz+mvtMlSAj5/X62bt1K8+bNufXWWxkyZAjdu3d3uiwRkTrPFS19g7r3I8X27ds599xz6d27N3l5ecTGxirwRUSqyBUtfQ3pR4b33nuP0aNHs2fPHmbMmEFiYqLTJYmIhBVXtPQ1e9/dysrKuOOOOxg4cCCpqaksW7aMa665RhM4RUSqyRWhr9/97maM4dNPP2XChAksX76cTp06OV2SiEhYckX3vlr67vSf//yH0047jaZNm7JgwQLi4uKcLklEJKyppS91TkFBAVdeeSUXXnghDzzwAIACX0SkBriipa+xXff46quvGDFiBGvWrOG2225j2rRpTpckIuIargh9jzLfFRYsWMAFF1xA/fr1eeeddxg4cKDTJYmIuIo7uvedLkBqRPfu3RkxYgRZWVkKfBGRWuCK0NdEvvD18ccfc9FFF1FSUkKDBg149tlnadKkidNliYi4kitCX2P64cfn83H33Xdzxhln8OWXX7Jp0yanSxIRcT2XhL7TFUh1bNq0ibPOOospU6YwYsQIVq5cSatWrZwuS0TE9TSRT0Ju5MiRrFy5kueee46xY8eqp0ZEJERcEfq64U7dV1xcjM/nIyEhgaeeegqv18vJJ5/sdFkiIhHFFd37xWU+p0uQw/juu+/o2bMn1113HQDt27dX4IuIOMAVob8rv8TpEqQC1lqee+45unXrxsaNG7ngggucLklEJKK5IvSPb6hbrNY1OTk5jB49mvHjx3PqqaeSlZXFueee63RZIiIRzRWhr4l8dc+uXbtYsGABd999N4sWLaJFixZOlyQiEvFcMZFPm/PUDX6/n9dee40LLriAVq1a8eOPP5KSkuJ0WSIiEuSKlr4m7ztv+/btnHPOOVx44YW8+eabAAp8EZE6Ri19OWqLFi1izJgx7NmzhyeeeIJzzjnH6ZJERKQCrmjpK/Kd87e//Y1BgwaRmprK8uXLufrqq7XZjohIHeWK0FdL3zldunRhwoQJZGZm0rFjR6fLERGRw3BH974rPrqEj5dffpkNGzZw8803M3DgQN0GV0QkTLgkLtXSD4X8/HyuuOIKhg8fzuuvv05ZWZnTJYmISDWEPPSNMbOMMZ8ZYyYd4vn6xpi3jTELjTGvGmNiKrum1unXvlWrVpGRkcGsWbO4/fbbef/994mKckVHkYhIxAhp6Btj/gB4rbW9gNbGmDYVnDYKmGGtHQRsBYZUft2arVN+bc+ePfTp04e9e/fy7rvvcu+99xIdHe10WSIiUk2hbqr1A14OHi8E+gBrDzzBWvvEAV+mAdsPvogx5krgSoCYpidqIl8tKSwsJD4+ntTUVObMmUPv3r1p3Lix02WJiMgRCnX3fiKwKXi8G2hyqBONMb2AVGvt5wc/Z62daa3NsNZmgGbv14aPP/6Yk08+mddffx2ACy64QIEvIhLmQh36eUB88DjpUK9vjGkAPApcFqK6JMjn8zFt2jTOOOMMYmJitGe+iIiLhDr0VxDo0gdIB9YffEJw4t4rwO3W2g1Vuaha+jXjl19+YcCAAdx1112MHDmSlStXkpGR4XRZIiJSQ0Id+q8BY4wxM4BhwGpjzPSDzrkc6ArcaYz5wBgzvLKL7swrrvlKI9DixYvJzMxkzpw5vPDCC9SrV8/pkkREpAYZa21oX9CYVGAg8KG1duvRXi+2WRv75yf+w70XaDe4I1FcXMzKlSvp1asX1lq2bNlC8+bNnS5LREQOwxizonxeW3WEfJ2+tXaPtfblmgj8csmxWi9+JL777jt69uzJwIED2bFjB8YYBb6IiIu5Y0c+DelXi7WW5557jm7durFx40bmz59PWlqa02WJiEgtc0XoG6V+lfl8PsaMGcP48eM59dRTycrK4txzz3W6LBERCQF3hL4yv8q8Xi+NGzfm7rvvZtGiRVqSJyISQVwxGK7MPzy/38+MGTM4/fTT6dGjBzNmzHC6JBERcYBa+i63bds2zj77bG6++WbmzZvndDkiIuIgl7T0lfoVWbhwIWPHjiU7O5snn3ySiRMnOl2SiIg4yB2hr8z/jffee4/BgwfTvn17Fi1axCmnnOJ0SSIi4jB3dO87XUAd4vP5AOjXrx8PPvggy5cvV+CLiAjgktBXUz/gpZdeon379mzduhWv18uf//xnEhISnC5LRETqCFeEfqRHfn5+PhMmTGDEiBE0aNCA0tJSp0sSEZE6yB2hH8Gpv2rVKjIyMpg9ezZ33HEHH374IS1btnS6LBERqYPcMZEvgtv69957L9nZ2bz77rsMGDDA6XJERKQOc0foR1jm7969m/z8fFq2bMkTTzyBz+fT3vkiIlIpd3TvO11ACH300Ud07tyZSy65BGstDRo0UOCLiEiVuCP0IyD1fT4f06ZNo1+/fsTGxvLwww9jIuEHFxGRGuOS7n13h9/27dsZNmwYS5YsYfTo0TzxxBMkJyc7XZaIiIQZV4S+2yUmJlJQUMCcOXMYO3as0+WIiEiYUvd+HVVUVMT06dPJz88nMTGRzz//XIEvIiJHxR2h77KpfN9++y09e/Zk8uTJvPHGGwB4PK74XyUiIg5yRZK4paVvrWX27Nl069aNTZs28cYbbzB8+HCnyxIREZdwR+g7XUANmT59Opdffjk9evQgKyuLc845x+mSRETERVwxkS/cW/rWWowxjBo1ipiYGP7v//4Pr9frdFkiIuIyLmnph2fq+/1+HnjgAYYNG4a1ltatW3Prrbcq8EVEpFa4I/TDMPO3bdvG2WefzS233ILf76eoqMjpkkRExOVcEfq780ucLqFaFi5cSHp6OkuWLOGpp57i3//+N/Hx8U6XJSIiLueKMf368dFOl1BlBQUFjBs3joYNG7Jo0SJOOeUUp0sSEZEI4YrQj4uu+2PgGzdupHnz5iQkJPDOO+9wwgknkJCQ4HRZIiISQVzRvV/XvfTSS5xyyincf//9AHTs2FGBLyIiIeeK0K+rE/ny8/OZMGECI0aMoEOHDlxyySVOlyQiIhHMHaHvdAEV+Oqrr8jIyGD27NnccccdLFmyhOOPP97pskREJIK5Yky/Ljb1CwsLKSgoYNGiRfTv39/pckRERNTSr0m7du1i9uzZAHTv3p21a9cq8EVEpM5wRejXBR9++CGdO3fm6quvZv369QDExMQ4W5SIiMgBXBH6Tvbul5WVMXXqVM4880zi4+P57LPPNHYvIiJ1kivG9J3ae99ay+9+9zvefvttxowZw+OPP05ycrIjtYiIiFTGHaHvUEvfGMMll1zCyJEjGTNmjDNFiIiIVJE7Qj+Er1VUVMTNN99M165dGT9+PKNHjw7hq4uIiBw5V4zph8qaNWvo0aMHjz32GD/88IPT5YiIiFSLO1r6tdzUt9by7LPPct1115GQkMCbb77J2WefXbsvKiIiUsNc0dKv7Yl8mZmZXH755fTo0YOsrCwFvoiIhCVXtPRrK/N37NhBWloap556KgsWLOCss87C6637d/QTERGpiCta+jXN7/fzt7/9jeOPP57ly5cDMHjwYAW+iIiENVe09Guyob9t2zbGjh3LwoULufDCCznxxBNr8OoiIiLOcUVL39TQTL6FCxeSnp7Ohx9+yFNPPcUrr7xCampqjVxbRETEaWrpH+Czzz6jUaNGvPfee3To0KGGrioiIlI3uKSlf+Tf+9NPP/HJJ58AMGnSJJYvX67AFxERV3JF6B+pefPm0blzZyZMmIDP58Pr9RIfH+90WSIiIrXCFaFf3ZZ+fn4+l112GZdccgkdO3ZkwYIFmpkvIiKu55Ix/aqn/o4dOzj99NP5/vvvmTRpEnfddRdRUa54G0RERA7LFWlXnZZ+o0aNOPPMM3nyySc588wza68oERGROsYV3fuV2bVrF6NGjeKnn37CGKPAFxGRiOT60F+yZAnp6em88sor+3bXExERiUSuCP2KNucpKytj6tSp9O/fn4SEBD7//HOGDx/uQHUiIiJ1gztCv4LHZsyYwV/+8hdGjx7NihUr6Nq1a8jrEhERqUtcN5EvLy+PpKQk/vjHP3LCCSdw4YUXOleYiIhIHeKKlj5AUVER1157Ld27dyc/P5/ExEQFvoiIyAFCHvrGmFnGmM+MMZOO5pwD/fLTD/To0YPHH3+cIUOGaN29iIhIBUIa+saYPwBea20voLUxps2RnHMgX0EON4wcwubNm3nzzTeZMWMGsbGxtfMDiIiIhLFQt/T7AS8HjxcCfY7wnH38hdm07dSNrKwszj777BoqU0RExH1C3Q+eCGwKHu8GKppSX+k5xpgrgSuDXxZnLfv46xYtWtRwqXKQRsBOp4twOb3HtU/vce3TexwaJx/JN4U69POA8tvYJVFxT0Ol51hrZwIzAYwxmdbajJovVQ6k97n26T2ufXqPa5/e49AwxmQe5Mp/1QAACNlJREFUyfeFunt/Bfu769OB9Ud4joiIiFRTqFv6rwEfGWOaA0OBEcaY6dbaSYc5p2eIaxQREXGlkLb0rbU5BCbqfQ6caa3NOijwKzonu5LLzqyFUuW39D7XPr3HtU/vce3TexwaR/Q+G2ttTRciIiIidZBrduQTERGRwwub0K+Nnfzk1yp7/4wx9Y0xbxtjFhpjXjXGxIS6Rjeo6t9TY0wTY8wXoarLTarxHj9hjDkvVHW5SRV+X6QaY94yxmQaY/4Z6vrcIvh74KPDPB9tjPmfMeYTY8xllV0vLEK/Nnbyk1+r4vs3CphhrR0EbAWGhLJGN6jm39MH2b98Vaqoqu+xMeZ0oKm19n8hLdAFqvgejwH+FVy+l2yM0TK+ajLGpAJzCOxfcyjXASustb2Bi4wxyYe7ZliEPrWwk5/8Rj8qef+stU9Ya98NfpkGbA9Naa7Sjyr8PTXG9AfyCXy4kurpRyXvsTEmGngaWG+M+X3oSnONflT+93gXcIoxJgVoCWwMTWmu4gOGAzmHOacf+/9ffAgc9sNVuIT+wbv0NTnCc+TQqvz+GWN6AanW2s9DUZjLVPo+B4dNJgO3hbAuN6nK3+WxwDfA34DuxpjrQlSbW1TlPf4YOA64HlgTPE+qwVqbU4UVbNXKvnAJ/RrZyU8Oq0rvnzGmAfAoUOnYkVSoKu/zbcAT1tq9IavKXaryHncBZlprtwIvAGeGqDa3qMp7fBdwlbX2/7d37zFyVnUYx7/PbpcWFMFAuMSA1dRws1oabRGNUqEpl6glaEyFpMUYhKBSING0CYomisaksaZoRAViooiiFhu5SJVVEgVFY7WKQaIQbInRxBpqS+vaxz/Ome3byW53tnupM/t8kkln3vfMmdM3u/ub91x+5xPAH4Erp6ltM824Yl+3BMZk8pt6Y16/egf6bWCN7Wemr2k9pZOf0wuAayUNAgskfWV6mtYzOrnGTwGvrM9fB+TneXw6ucYvBeZL6gcWA1kfPjXGFfu6Yp2+pJcAjwA/ombyA97VTOwzQplzOugWiarDa3wN8ClgSz30Rdt3T3dbu1kn17mt/KDt86avhd2vw5/lo4HbKV2hA8A7bW8boboYQYfXeBFwB6WL/+fApbZ3Hobmdr3W34E61+dM2xsa514O3AdsBs6lxL7/jlpXNwR9GJ7FuBT4ae2SO6QyMbpcv+mR6zz1co2nXq7x/4+atv5NwINj3ex2TdCPiIiIiemWMf2IiIiYoAT9iIiIGSJBPyKmnKR+STrc7YiY6RL0I3qEpOWSzh3l3Jyp3CtB0jJJNzZe3yLpwUaRjwKb6vKtTuq7vCaBiohJNOtwNyAiJs1NwI8lraOsi25ZA8wFVkgyJYHHtba/BCDpbOAFxl5H3Q/MAX5ne2/buX8BayWdYPsjwB5gd63/YuDDwHvalxLVdLizgD229zVOvRfYBbytUbYfOALYZ3vPGG2NiBEk6Ef0AEmnAvOBtwOLgCW2ByXdSQmoVwNX17KDlCxeLY9SgnQz6B5BCfDNnN999fhp1GQ2kmYDAn4BXAKsH2HDjxuAa2y3dmbss/1CPfduYAOwW1IrkA9QvoAMSXq6Uc8AcBRlI6JPdnRhIuIACfoRvWElZaetbfVufizDd9y2Z7eflLQKuNn23DHq+QxwXdux4S8KjbacL+mO+vxeYHl9flf99wHb/6jvuQs4tpZZAPzS9r66k9sllDTQEXEIMqYf0eUkzQLeR7lbb3m4BtyVwBxJmyU9L2kHJYnHwbbqHI+bgeOAAdsC5gHPAU9SgvsZwPcpwwt9lN6DFY33HwmcAzwpaamke4CTKHnb1wI/AS6q+4Q/Dpxc64iIQ5A7/YjudyVlnL5pie3B1gtJ6ynd93s8QkYuSdcBu2x/eTwf3NwUqKYI/UZ9PE/Z1GYn5QvGVuBG27e1vX8n8AFJtwF7gcsoPQUPUb4QXGr7B3XewUrbG8fTvog4UO70I7pYHcv/NPCFUc7PkXQCZSvZFcBKSaskvbqt6FLgzW3H+iQd23gcL+nkET7jtbVLfhNwi+0bKGP/s23/tdb9MeBWSZtqe9r9G9hBmZfwVso8gSuAl0laSNmbfV6W/UVMTIJ+RHfbTgmov2o73ure3w2cAnwWuJwyTr4OeFVb+SEa4/zVKcA/G4+/A/c3C0h6PfBrygS7BbbXN9q1Q1K/i3WUjVlOpe3vjqSLgMeA8ym9AvdSZu9/B1hG2RhnLmUVwj2SjhrrokTEyBL0I7qY7aHmjlsNS+oY+5GUoHwfsMH2cko3+uMdVP+MbbUelNnz7XkAtgJn2X6H7T+1nVtEY0WA7c312PDKAUlrga9ReiKeoOzGdjTwecoywMXAWcBCyha4r6HM+I+IQ5Ax/YgeVbvCW93hm4ELJf2WMnb/7Hjrsz1E6RFouh94y0F63feNck6S+oBvAt+y/VQ9uJiyH/hXgT/bXl23aH3W9nOSFgCuPQijbh8aESNL0I/oTQ83nr8C+C4lK56BWyfxcy6udQ4n15F0GvAbYBuwyfb1rcJ1nX5rieB8yrDEXkntyX5eRPnCsKrxXtifK2AZZWZ/RIxDgn5Eb2ol5xkAhmxb0g8pY+UnTdaH2N7VfF339f46pcv+48DPao/DGtu7aya/vfW9Wxjlb5CkjcDTtldPVlsjImP6Eb2in/2/zwOtg7b/A7xY0k3AhcAW4HZJJ9ZNcBZIOoOy5O8YSadLOp2yHn6g9bo+zqzl57V/uKTjJF1PucN/AviQ7e3AGyhj8VslfVDSMVN3CSJiLLnTj+gNc9iftGY4w17dgOcByoz4hZRZ+J8D/kCZFPcYB+bdf7St3vbXA7W+y2r9qylLAc8Gfg+83/b3WoXrOPx5wFWURD7rJN1t+4ox/j/NLzERMUk0Qp6OiOghkk60/be2Y8e30t5OsO43AhcAG2t3/cHKzqYsGdxu+5Exyj4E/MX2VRNtY0Tsl6AfERExQ6T7LCIiYoZI0I+IiJghEvQjIiJmiAT9iIiIGSJBPyIiYoZI0I+IiJgh/gc0dOXYpQkmQgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif']=['SimHei']\n",
    "def plot_roc_curve(fpr,tpr,label=None):\n",
    "    plt.plot(fpr,tpr,linewidth=2,label=label)\n",
    "    plt.plot([0,1],[0,1],'k--')\n",
    "    plt.axis([0,1,0,1])\n",
    "    plt.xlabel('假正类率',fontsize=16)\n",
    "    plt.ylabel('真正类率',fontsize=16)\n",
    "\n",
    "plt.figure(figsize=(8,6))\n",
    "plot_roc_curve(fpr,tpr)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9636817494239135"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算曲线下方的面积AUC\n",
    "from sklearn.metrics import roc_auc_score\n",
    "roc_auc_score(y_train_5,y_scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * 召回率tpr越高，分类器的假正类FPR越多\n",
    "   * 虚线表示纯随机分类器的ROC曲线，好的分类器ROC曲线应该原理这条曲线向左上角\n",
    "   * 正类非常少或者更关注假正类而不是假负类时，选择PR曲线，反之选择ROC\n",
    "   * 例如：本例中ROC曲线比较理想是因为跟负类 非5 ，正类数据5很少"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练随机森林分类器，比较SGD分类器的曲线和ROC AUC分数\n",
    "   * 获取训练集中的每个实例的分数\n",
    "   * RandomForestClassifier（随机森林分类器）没有decision_function()方法，但是有dict_proda()方法，返回每个实例是正类或是负类的概率，sklearn中的每个分类器中都有这两个中的一个\n",
    "   * dict_proda返回一个矩阵，每行一个实例，每列代表一个类别是正类或负类的概率，比如某张图片有70%的概率是5,有30%的概率不是5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "forest_clf = RandomForestClassifier(n_estimators = 10,random_state = 42)\n",
    "y_probas_forest = cross_val_predict(forest_clf,X_train,y_train_5,cv=3,\n",
    "                                    method=\"predict_proba\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1. , 0. ],\n",
       "       [0.9, 0.1],\n",
       "       [1. , 0. ],\n",
       "       ...,\n",
       "       [1. , 0. ],\n",
       "       [0.9, 0.1],\n",
       "       [1. , 0. ]])"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_probas_forest"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   * 绘制ROC曲线需要的是决策值，而不是概率，直接使用正类的概率作为决策值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_scores_forest = y_probas_forest[:,1] #冒号代表取所有的行，1代表取第一列\n",
    "fpr_forest,tpr_forest,threshold_forest = roc_curve(y_train_5,y_scores_forest) #获取真正类率，假正类率和阀值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0. , 0.1, 0. , ..., 0. , 0.1, 0. ])"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_scores_forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,6))\n",
    "plt.plot(fpr,tpr,\"b:\",linewidth=2,label=\"SGD\")\n",
    "plot_roc_curve(fpr_forest,tpr_forest,\"Random Forest\")\n",
    "plt.legend(loc=\"lower right\",fontsize=16)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9934162323473652"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Random Forest效果比SGD好很多，ROC，AUC的分数也高很多\n",
    "roc_auc_score(y_train_5,y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9856146469049695"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 召回率和进度也很高\n",
    "y_train_pred_forest = cross_val_predict(forest_clf,X_train,y_train_5,cv=3)\n",
    "precision_score(y_train_5,y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8341634384799852"
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5,y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "   * 选择合适的指标利用交叉验证来对分类器进行验证\n",
    "   * 选择满足需求的精度/召回率权衡\n",
    "   * 使用ROC曲线和ROC AUC分类比较多个模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多类别分类器\n",
    "   * 尝试5之外的检测\n",
    "   * 多类别分类器区分两个以上的类别\n",
    "   * 随机森林和朴素贝叶斯可以直接处理多个类别\n",
    "   * 支持向量机SVM和线性分类器只可以处理二元分类器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 解决方案\n",
    "   1. 方案一将数字图片分类为0到9，训练10个分类器，每个数字一个，检测一张图片时，获取每个分类器的决策分数，哪个最高则判断属于哪个，称为1对多 OvA\n",
    "   2. 为每一对数字训练一个二元分类器，区分0/1,0/2,1/2,....，称为一对一OvO策略，存在N个类别时需要N*(N-1)/2个分类器，最后看哪个类别获胜最多"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 优缺点\n",
    "   * OvO只需要用到部分训练集，必须对其区分两个类别进行训练\n",
    "   * 对于较小训练集合OvO比较有优势，大训练集合OvA速度快，所以OvA更常用，比如SVM在数据规模扩大时表现糟糕\n",
    "   * sklearn检查到使用二元分类算法进行多类别分类任务，会自动运行OvA，SVM分类器除外"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.fit(X_train,y_train)\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ -5277.61156837, -25457.93409217,  -9113.97344121,\n",
       "           984.78602159, -12261.49816666,   1526.26354507,\n",
       "        -21693.47301313, -19620.06643828, -12159.93137471,\n",
       "         -9621.72794556]])"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 内部实际上训练了10个二元分类器，获得图片的决策分数，最后选择了分数最高的类别\n",
    "# 返回10个分数，每个类别1个\n",
    "some_digit_scores = sgd_clf.decision_function([some_digit])\n",
    "some_digit_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argmax(some_digit_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 目标类别列表会存储在classes_这个属性中，按值的大小排列\n",
    "sgd_clf.classes_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.classes_[np.argmax(some_digit_scores)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3.])"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用OvO策略，一对一或着一对多\n",
    "from sklearn.multiclass import OneVsOneClassifier\n",
    "ovo_clf = OneVsOneClassifier(SGDClassifier(max_iter=5,tol=-np.infty,random_state=42))\n",
    "ovo_clf.fit(X_train,y_train)\n",
    "ovo_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "45"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(ovo_clf.estimators_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#使用随机森林多元分类器\n",
    "forest_clf.fit(X_train,y_train)\n",
    "forest_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.1, 0. , 0. , 0. , 0.2, 0.6, 0.1, 0. , 0. , 0. ]])"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 随机森林直接将实例分为多个类别，调用predict_proba()可以获得每个分类器将实例分为每个类别的概率列表\n",
    "forest_clf.predict_proba([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 评估分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.87327534, 0.85054253, 0.85652848])"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用交叉验证评估SGD的准确率\n",
    "cross_val_score(sgd_clf,X_train,y_train,cv=3,scoring='accuracy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\think\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\linear_model\\stochastic_gradient.py:561: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.\n",
      "  ConvergenceWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.9015197 , 0.90154508, 0.90453568])"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将输入进行简单缩放，可以得到准确率90%以上\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))\n",
    "cross_val_score(sgd_clf,X_train_scaled,y_train,cv=3,scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 错误分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 项目流程\n",
    "   1. 探索数据，准备数据，加载数据\n",
    "   2. 尝试多个模型\n",
    "   3. 选择最佳模型并用GridSearchCV（网格搜索）对参数进行微调\n",
    "   4. 尽可能自动化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 确定了一个相对合适的模型，进一步优化，分析其错误类型\n",
    "   * 查看混淆矩阵\n",
    "   * 使用cross_val_predict()进行预测\n",
    "   * 调用confusion_matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\think\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\linear_model\\stochastic_gradient.py:561: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.\n",
      "  ConvergenceWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[5604,    0,   14,    8,   10,   39,   35,    5,  207,    1],\n",
       "       [   0, 6419,   46,   24,    3,   44,    5,    9,  181,   11],\n",
       "       [  26,   26, 5260,   94,   75,   22,   67,   37,  339,   12],\n",
       "       [  27,   17,  124, 5262,    1,  209,   26,   47,  355,   63],\n",
       "       [  13,   13,   48,   10, 5235,    9,   37,   20,  289,  168],\n",
       "       [  28,   16,   30,  155,   56, 4512,   85,   17,  452,   70],\n",
       "       [  31,   18,   44,    3,   34,   87, 5569,    5,  127,    0],\n",
       "       [  21,   14,   53,   25,   47,   12,    5, 5719,  161,  208],\n",
       "       [  16,   60,   42,   99,    3,  123,   33,    7, 5421,   47],\n",
       "       [  24,   22,   29,   59,  130,   35,    1,  183,  315, 5151]],\n",
       "      dtype=int64)"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_pred = cross_val_predict(sgd_clf,X_train_scaled,y_train,cv=3)\n",
    "conf_mx = confusion_matrix(y_train,y_train_pred)\n",
    "conf_mx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#使用matplotlib的matshow函数来查看混淆矩阵的图像表示\n",
    "plt.matshow(conf_mx,cmap=plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 大多数图片在主对角线上，被正确分类\n",
    "# 数字5的区域比较暗，说明1.数字5的图片较少 2.分类器在数字5上执行效果不如其他数字\n",
    "# 假设把焦点放在错误上，为取得错误率，而不是错误的绝对值，需要将混淆矩阵中每个值除以相应类别中的图片数量\n",
    "row_sums = conf_mx.sum(axis=1,keepdims=True)\n",
    "norm_conf_mx = conf_mx/row_sums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#用0填充对角线(纯黑色），只保留错误，重新绘制\n",
    "np.fill_diagonal(norm_conf_mx,0)\n",
    "plt.matshow(norm_conf_mx,cmap=plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 每行代表实际类别，每列代表预测类别\n",
    "# 8,9,列比较亮，说明许多图片被错误的分类为数字8,9\n",
    "# 类别8,9也偏亮，说明数字8和9经常会跟其他数字混淆\n",
    "# 有些很暗，比如行1，大多数数字1都被正确的分类，一些和8混淆\n",
    "# 5和3是最容易混淆的"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 结论\n",
    "   * 改进数字8和9的分类\n",
    "   * 修正数字3和5的混淆\n",
    "   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 如何优化分类器\n",
    "   * 尝试多收集这些数字的训练集\n",
    "   * 开发一些新特征来改进分类器\n",
    "   * 优化分类器算法\n",
    "   * 使用pillow或opencv对图片预处理，让显示模型更加突出\n",
    "   * 分析单个错误"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [],
   "source": [
    "# SGD是一个线性模型，他所做的就是为每个像素分配一个各个类别的权重，当他接受到新的图像，将加权后的像素强度汇总，从而的得到一个分数进行分类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多标签分类\n",
    "   * 为每个实例生成多个类别，例如识别照片中的多个人脸\n",
    "   * 分类器经过训练可以识别a,b,c三个人,一张照片里有a,b两个人，经过分类器应该输出[1,1,0]\n",
    "   * 输出多个二元标签的分类系统称为多标签分类系统"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "                     weights='uniform')"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier #K近邻 KNN算法\n",
    "y_train_large = (y_train >= 7)\n",
    "y_train_odd = (y_train %2 == 1)\n",
    "y_multilabel = np.c_[y_train_large,y_train_odd]\n",
    "\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train,y_multilabel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False,  True]])"
      ]
     },
     "execution_count": 128,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# knn支持多标签分类，不是所有的分类器都支持\n",
    "knn_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 评估多标签分类器的方法很多，方法之一是测量每个标签的F1分数，或者其他二元分类器指标，然后简单平均\n",
    "# y_train_knn_pred = cross_val_predict(knn_clf,X_train,y_multilabel,cv=3)\n",
    "# f1_score(y_multilabel,y_train_knn_pred,average=\"marco\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 以上设置的每个标签都同等重要，也可以给每个标签设置一个权重（该目标标签实例的数量），设置average='weighted'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多输出分类 \n",
    "### 构建一个系统去除图片中的噪声，输入一张有噪声的图片，系统将输出一张干净的数字图片，分类器输出多个标签，一个像素一个标签，每个标签多个值0-255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 增加噪声，目标：将图片还原为原始图片创建训练集和测试集\n",
    "noise= np.random.randint(0,100,(len(X_train),784))\n",
    "X_train_mod=X_train + noise\n",
    "noise= np.random.randint(0,100,(len(X_test),784))\n",
    "X_test_mod = X_test + noise\n",
    "y_train_mod = X_train\n",
    "y_test_mod = X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "some_index = 5500\n",
    "plt.subplot(121);plt.imshow(X_test_mod[some_index].reshape(28,28),cmap=matplotlib.cm.binary)\n",
    "plt.subplot(122);plt.imshow(y_test_mod[some_index].reshape(28,28),cmap=matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn_clf.fit(X_train_mod,y_train_mod)\n",
    "clean_digit = knn_clf.predict([X_test_mod[some_index]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(clean_digit.reshape(28,28),cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
